/*******************************************************************************
 *  Form class
 *  desc: Wrapper for FormElement
 *******************************************************************************

// options example
var options = {
    id: 'id',
    title: 'title',
    showTitle: true,
    description: 'description',
    target: 'targetElement',
    butons: {
        finish: {
            onclick: handler,
            title: 'Title'
        },
        next: {
            ...
        },
        previous: {
            ...
        }
    }
}
*/

var Wizard = function(options){
    
    // this class should extend an Element class
    $.extend(true, this, new Form(options))
    
    // ------------------------------------------------------- fields
    this.stepIndex = 0;
    this.buttonsHolder = null;
    
    // ------------------------------------------------------- core methods
    this._prepareStep = function(options){
        var step = uic.step(options);
        var controls = options.fields;
        for(var i = 0; i < controls.length; i++){
            var control = this._prepareControl(controls[i]);
            if(!control){
                console.log('Control was not found');
                continue;
            }
            step.add(control);
        }
        
        return step;
    }
    
    this._prepareControl = function(options){
        var field = options.template.element;
        
        switch (field.tag) {
            case "input":
                switch (field.type) {
                    case "text":
                        return uic.control.input(options);
                    case "checkbox":
                        return uic.control.checkbox(options);
                    case "password":
                        return uic.control.password(options);
                }
                break;
            case "select":
                return uic.control.dropdown(options);
            default:
                Notifier.error('Control for '+field.tag+'['+field.type+'] was not found.');
        }
        return null
    }
    // ------------------------------------------------------- methods
    
    /**
     *  Adds a step to wizard
     *  @param step defines wizard step
     *  @return class instance
     */
    this.addStep = function(step){
        if(step && step instanceof Step) {
            step.getElement().hide();
            this.formElement.append(step);
            this.steps.push(step);
            this._bindValidationHandler(step)
        }
        return this;
    };
    
    this._hideAll = function(){
        for(var i=0; i<this.steps.length; i++){
            var step = this.steps[i];
            step.getElement().hide();
            step.isShown = false;
        }
    }
    
    this._showCurrentStep = function(){
        var step = this.getStepByIndex(this.stepIndex);
        step.getElement().show();
        step.isShown = true;
        
        // prepares step title
        if(this.stepTitle) this.stepTitle.remove();
        this.stepTitle = step.title;
        var stepInfo = step.title.find('b.step-info');
        stepInfo.text($.validator.format(stepInfo.text(), this.stepIndex+1, this.steps.length));
        stepInfo.show();
        this.formElement.getElement().before(this.stepTitle);
    }
    
    this.next = function(){
        this.stepIndex = this.stepIndex+1;
        this.show();
    }
    
    this.prev = function(){
        this.stepIndex = this.stepIndex-1;
        this.show();
    }
    
    this.show = function(){
        console.info(this.steps);
        this._prepareButtons();
        this._hideAll();
        this._showCurrentStep();
        return this;
    }
    
    this._createButtons = function(){
        var buttons = new Array();
        
        this.buttons = {
            previous: this._getPreviousButton(),
            next: this._getNextButton(),
            finish: this._getFinishButton(),
            cancel: this._getCancelButton()
        }
        
        buttons.push(this.buttons.previous);
        buttons.push(this.buttons.next);
        buttons.push(this.buttons.finish);
        buttons.push(this.buttons.cancel);
        
        this._getButtonsHolder().getElement().html('') // clear all
        for(var i=0; i<buttons.length; i++){
            this.addButton(buttons[i]);
        }
        this.buttons.array = buttons;
    }
    
    this._disableAllButtons = function(){
        var buttons = this.buttons.array;
        for(var i=0; i<buttons.length; i++){
            buttons[i].getElement().hide();
        }
    }
    
    this._prepareButtons = function(){
        this._disableAllButtons();
        this.formElement.append(this._getButtonsHolder());
        
        // prepares prev button
        if(this._getPreviousStep()) this.buttons.previous.getElement().show();
        
        // prepares next/finish button
        if(this._getNextStep()){
            this.buttons.next.getElement().show();
        } else {
            this.buttons.finish.getElement().show();
        }
        // prepares cancel button
        this.buttons.cancel.getElement().show();
    }
    
    this._getCancelButton = function(){
        return new ButtonElement({
            onclick: function(){
                // TODO: 
                Notifier.warning('Cancel button was pressed')
            },
            id: 'cancel',
            title: 'Cancel'
        }) 
    }
    
    this._getFinishButton = function(){
        var form = this;
        
        var buttonDefaults = {
            onclick: function(){
                var result = new Array();
                var steps = options.steps;
                for(var i = 0; i < steps.length; i++){
                    var step = steps[i];
                    var fields = step.fields;
                    for(var j = 0; j < fields.length; j++){
                        var field = fields[j];
                        var $element = $(field.template.element.tag+'[id='+field.id+']');
                        result.push({
                            id: field.id,
                            value: $element.val()
                        });
                    }
                }
                console.log(result);
                $.myAjax({
                    url: Wizard.url.save,
                    data: {
                        step: JSON.stringify({fields: result})
                    },
                    type: "POST",
                    success: function(result) {
                        Notifier.success('Wizard data was saved');
                    }
                });
            },
            id: 'finish',
            title: 'Finish',
            primary: true
        }
        
        var buttonSettings;
        if(form.settings.buttons && form.settings.buttons.finish){
            buttonSettings = $.extend({}, buttonDefaults, form.settings.buttons.finish);
        } else {
            buttonSettings = buttonDefaults;
        }
        
        return new ButtonElement(buttonSettings);
    }
    
    this._getNextButton = function(){
        
        var form = this;
        return new ButtonElement({
            onclick: function(){
                form.next();
            },
            id: 'next',
            title: 'Next',
            primary: true
        });
    }
    
    this._getPreviousButton = function(){
        
        var form = this;
        return new ButtonElement({
            onclick: function(){
                form.prev()
            },
            id: 'previous',
            title: 'Previous'
        })
    }
    
    this._getPreviousStep = function(){
        return this.getStepByIndex(this.stepIndex-1)
    }
    
    this._getNextStep = function(){
        return this.getStepByIndex(this.stepIndex+1)
    }
    
    // ------------------------------------------------------- preparing
    console.info(options);
    this._createButtons();
    
    var steps = options.steps;
    
    if(steps){
        for(var i = 0; i < steps.length; i++){
            this.addStep(this._prepareStep(steps[i]));
        }
        if(steps.length>0) this.show();
    }
    console.log('Wizard was created with id = '+this.getId());
}

Wizard.requestData = function(id){
    var data;
    $.ajax({
        url: Wizard.url.get,
        type: "POST",
        data: {
            id: id
        },
        async: false,
        success: function(result) {
            data = result;
        }
    });
    return data;
    
}

Wizard.getInstance = function(id){
    return new Wizard(Wizard.requestData(id));
}

Wizard.url = {
    save: '',
    get: ''
}